﻿#ifndef TRANSMITCODEC_H
#define TRANSMITCODEC_H

#include <qobject.h>
#include "ObjAutoInject.h"
#include <qbytearray.h>
#include <qhash.h>
#include <qtimer.h>

class TransmitRecord;
class RegisterCenter_Device;
class RegisterCenter_User;
class UdpCodec;
class TcpCodec;
class ScriptRunner;
class TransmitCodec : public QObject, public ObjAutoInject
{
  Q_OBJECT
public:
  enum Result{
    Succeed=0,//发送成功，在设备返回确认报文后发送给客户端
    Sending,//正在发送，收到客户端指令并转发无误后发送给客户端
    CantSend,//不能发送，当前正在下发指令，不能再次发送指令
    Offline,//设备离线，设备处于离线状态
    TimeOut,//发送超时，发送指令时设备连接超时，此时设备也处于离线状态
    ErrorData,//错误数据，客户端指令格式不正确
    Size_Result//枚举类大小，用于默认返回值，遇到该值不做处理
  };
  /*
 * deviceId设备编号，32bit
 * MCU操作类型8bit，后续载荷中的数据由子解析器解析
 * 操作数据
*/
private://property
  QHash<unsigned int/*deviceId*/,TransmitRecord*> dataRecordMap;
  QHash<uchar,uchar> tcpTypeToUdpTypeMap;
  QHash<uchar,uchar> udpTypeToTcpTypeMap;
private://dependency
  RegisterCenter_Device* registerCenter_Device=Q_NULLPTR;
  RegisterCenter_User* registerCenter_User=Q_NULLPTR;
  UdpCodec* udpCodec=Q_NULLPTR;
  TcpCodec* tcpCodec=Q_NULLPTR;
  ScriptRunner* scriptRunner=Q_NULLPTR;
public:
  explicit TransmitCodec();
  virtual ~TransmitCodec();
signals:
  void signal_sendReady(uint deviceId);
public:
  void decode_udp(uint deviceId,ushort msgId,uchar type,QByteArray data);
  void decode_tcp(uint deviceId,uint userId,uchar type,QByteArray data);
  bool isCanSendInstruction(unsigned int deviceId);
private:
  void repeatSendData(uint deviceId);
  void removeDataRecord(uint deviceId);
public://geter and seter
  RegisterCenter_Device* getRegisterCenter_Device()const;
  TransmitCodec* setRegisterCenter_Device(RegisterCenter_Device* const registerCenter_Device);
  RegisterCenter_User* getRegisterCenter_User()const;
  TransmitCodec* setRegisterCenter_User(RegisterCenter_User* const registerCenter_User);
  UdpCodec* getUdpCodec()const;
  TransmitCodec* setUdpCodec(UdpCodec* const udpCodec);
  TcpCodec* getTcpCodec()const;
  TransmitCodec* setTcpCodec(TcpCodec*const tcpCodec);
  ScriptRunner* getScriptRunner()const;
  TransmitCodec* setScriptRunner(ScriptRunner*const scriptRunner);
public:
  virtual void objectAutoInjection(QHash<QString,QObject*>* objMap)override;
};

#endif // TRANSMITCODEC_H
